#include "stdafx.h"
#include "resource_manager.h"
#include <stdio.h>
#include <stdlib.h>

BOOL CreateDepthDirectory(const wstring& path, const wstring& parent)
{
	BOOL bRetVal = FALSE;
	wstring::size_type fpos = path.find('\\');
	wstring dir = path, sub, dest;
	if ( fpos != wstring::npos )
	{
		dir = path.substr(0, fpos);
		sub = path.substr(fpos+1);
	}

	if ( !parent.empty() )
	{
		dest = parent + L"\\" + dir;
	}
	else
	{
		dest = dir;
	}

	bRetVal = CreateDirectoryW( dest.c_str(), NULL );
	if ( bRetVal || ( ERROR_ALREADY_EXISTS == GetLastError() ) )
	{
		if ( !sub.empty() )
		{
			bRetVal = CreateDepthDirectory( sub, dest );
		}
	}

	return bRetVal;
};

void res_file::clear()
{
	prefix.clear();
	count = 0;
	items.clear();
}

resource_manager::resource_manager(void)
{
}


resource_manager::~resource_manager(void)
{
}

bool resource_manager::extract_resource_files(const wstring& filename, const wstring& cachedir)
{
	bool retval = false;

	resfile.clear();

	FILE* pf = NULL;
	_wfopen_s(&pf, filename.c_str(), L"rb");
	if ( pf == NULL )
		return retval;

	CreateDepthDirectory( cachedir.c_str(), L"");

	size_t filesize, readsize;
	fseek(pf, 0, SEEK_END);
	filesize = (size_t)ftell(pf);
	fseek(pf, 0, SEEK_SET);

	char* data = new char[filesize];

	readsize = fread(data, 1, filesize, pf);
	if ( readsize == readsize )
	{
		retval = unpack( cachedir, data, filesize );
	}

	delete[] data;

	fclose(pf);
	return retval;
}

bool resource_manager::restore_resource_files(const wstring& filename, const wstring& cachedir)
{
	return true;
}

bool resource_manager::pack(const wstring& cachedir, const char* data, unsigned int size)
{
	return true;
}

bool resource_manager::unpack(const wstring& cachedir, const char* data, unsigned int size)
{
	int offset = 0;	
	resfile.prefix.assign( data+offset, 16 );
	offset += 16;

	resfile.count = *((unsigned int*)(data+offset));
	offset += sizeof(unsigned int);

	resfile.items.resize(resfile.count);

	resfile.prefix_size = *((unsigned __int64*)(data+offset));
	offset += sizeof(unsigned __int64);

	resfile.file_desc_size = *((unsigned __int64*)(data+offset));
	offset += sizeof(unsigned __int64);

	int typelen = sizeof(unsigned __int64);
	int wcharlen = sizeof(wchar_t);
	size_t i = 0;
	for ( i = 0; i < resfile.count; i++ )
	{
		do
		{
			wchar_t wch = *((wchar_t*)(data+offset));
			offset += wcharlen;
			resfile.items[i].name += wch;
			if ( wch == '\0' )
				break;
			
		}while(true);

		resfile.items[i].offset = *((unsigned __int64*)(data+offset));
		offset += typelen;
		resfile.items[i].size = *((unsigned __int64*)(data+offset));
		offset += typelen;		
	}


	unsigned __int64 data_base_offset = resfile.prefix_size + resfile.file_desc_size;
	for ( unsigned int i = 0; i < resfile.count; i++ )
	{
		size_t data_len = resfile.items[i].size;
		size_t data_offset = data_base_offset + resfile.items[i].offset;
		extract_res_file( cachedir, resfile.items[i].name, data+data_offset, data_len);
	}


	return true;
}

void resource_manager::extract_res_file(const wstring& cachedir, const wstring& filename, const char* data, unsigned int size)
{
	wstring path = cachedir + filename;

	wstring::size_type fpos = path.rfind('\\');
	wstring directory;
	if ( fpos != wstring::npos )
	{
		directory = path.substr(0, fpos);
		CreateDepthDirectory( directory.c_str(), L"" );
	}

	FILE* pf = NULL;
	_wfopen_s(&pf, path.c_str(), L"w+b");
	if ( pf == NULL )
		return;

	size_t writesize = fwrite(data, size, 1, pf);

	fclose(pf);
}

